{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "from keras.callbacks import LambdaCallback\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Activation\n",
    "from keras.layers import LSTM\n",
    "from keras.optimizers import RMSprop, Adam\n",
    "from keras.utils.data_utils import get_file\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import random\n",
    "import sys\n",
    "import io\n",
    "import re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "songs = pd.read_csv('data/drake-songs.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "367372"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text = ''\n",
    "\n",
    "for index, row in songs['lyrics'].iteritems():\n",
    "    cleaned = str(row).lower().replace(' ', '\\n')\n",
    "    text = text + \" \".join(re.findall(r\"[a-z']+\", cleaned))\n",
    "    \n",
    "len(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total chars: 28\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "tokens = re.findall(r\"[a-z'\\s]\", text)\n",
    "\n",
    "chars = sorted(list(set(tokens)))\n",
    "print('total chars:', len(chars))\n",
    "char_indices = dict((c, i) for i, c in enumerate(chars))\n",
    "indices_char = dict((i, c) for i, c in enumerate(chars))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[' ',\n",
       " \"'\",\n",
       " 'a',\n",
       " 'b',\n",
       " 'c',\n",
       " 'd',\n",
       " 'e',\n",
       " 'f',\n",
       " 'g',\n",
       " 'h',\n",
       " 'i',\n",
       " 'j',\n",
       " 'k',\n",
       " 'l',\n",
       " 'm',\n",
       " 'n',\n",
       " 'o',\n",
       " 'p',\n",
       " 'q',\n",
       " 'r',\n",
       " 's',\n",
       " 't',\n",
       " 'u',\n",
       " 'v',\n",
       " 'w',\n",
       " 'x',\n",
       " 'y',\n",
       " 'z']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nb sequences: 122444\n"
     ]
    }
   ],
   "source": [
    "# cut the text in semi-redundant sequences of maxlen characters\n",
    "maxlen = 40\n",
    "step = 3\n",
    "sentences = []\n",
    "next_chars = []\n",
    "\n",
    "for i in range(0, len(text) - maxlen, step):\n",
    "    sentences.append(text[i: i + maxlen])\n",
    "    next_chars.append(text[i + maxlen])\n",
    "    \n",
    "print('nb sequences:', len(sentences))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vectorization...\n"
     ]
    }
   ],
   "source": [
    "print('Vectorization...')\n",
    "\n",
    "x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)\n",
    "y = np.zeros((len(sentences), len(chars)), dtype=np.bool)\n",
    "\n",
    "for i, sentence in enumerate(sentences):\n",
    "    for t, char in enumerate(sentence):\n",
    "        x[i, t, char_indices[char]] = 1\n",
    "    y[i, char_indices[next_chars[i]]] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Build model...\n"
     ]
    }
   ],
   "source": [
    "# build the model: a single LSTM\n",
    "print('Build model...')\n",
    "model = Sequential()\n",
    "model.add(LSTM(128, input_shape=(maxlen, len(chars))))\n",
    "model.add(Dense(len(chars)))\n",
    "model.add(Activation('softmax'))\n",
    "\n",
    "model.compile(loss='categorical_crossentropy', optimizer=RMSprop(lr=0.01))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "lstm_1 (LSTM)                (None, 128)               80384     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 28)                3612      \n",
      "_________________________________________________________________\n",
      "activation_1 (Activation)    (None, 28)                0         \n",
      "=================================================================\n",
      "Total params: 83,996\n",
      "Trainable params: 83,996\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sample(preds, temperature=1.0):\n",
    "    preds = np.asarray(preds).astype('float64')\n",
    "    preds = np.log(preds) / temperature\n",
    "    exp_preds = np.exp(preds)\n",
    "    preds = exp_preds / np.sum(exp_preds)\n",
    "    probas = np.random.multinomial(1, preds, 1)\n",
    "    return np.argmax(probas)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def on_epoch_end(epoch, logs):\n",
    "    print('----- Generating text after Epoch: %d' % epoch)\n",
    "\n",
    "    start_index = random.randint(0, len(text) - maxlen - 1)\n",
    "    for diversity in [0.2, 0.5]:\n",
    "        print('----- diversity:', diversity)\n",
    "\n",
    "        generated = ''\n",
    "        sentence = text[start_index: start_index + maxlen]\n",
    "        generated += sentence\n",
    "        print('----- Generating with seed: \"' + sentence + '\"')\n",
    "        sys.stdout.write(generated)\n",
    "\n",
    "        for i in range(400):\n",
    "            x_pred = np.zeros((1, maxlen, len(chars)))\n",
    "            for t, char in enumerate(sentence):\n",
    "                x_pred[0, t, char_indices[char]] = 1.\n",
    "\n",
    "            preds = model.predict(x_pred, verbose=0)[0]\n",
    "            next_index = sample(preds, diversity)\n",
    "            next_char = indices_char[next_index]\n",
    "\n",
    "            generated += next_char\n",
    "            sentence = sentence[1:] + next_char\n",
    "\n",
    "            sys.stdout.write(next_char)\n",
    "            sys.stdout.flush()\n",
    "        print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "122444/122444 [==============================] - 89s 726us/step - loss: 1.3089\n",
      "----- Generating text after Epoch: 0\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"l in love with the rollie i wake up and \"\n",
      "l in love with the rollie i wake up and i want that you have to be the way i want that i want that i want that i was and i still and i still and i say it was all this all the way i'm gone that i want that i want that i want that i want that you can take the way i want that i want that i want that you want that i want that i was all that i want that i want that i want that i want that i won't want that i want that i won't wanna save you \n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"l in love with the rollie i wake up and \"\n",
      "l in love with the rollie i wake up and the hate get it i need a get it i get it i get it i'm trying to you don't wanna fuck it i'm the way it was boy it all the can't stane that you know you don't tried to make all the lost and you know the way not flowing on the bands done have you that i'm still her and the way who the panting and i see me when you need to back in the changed the with the night and i all way it like it i won't wanna \n",
      "Epoch 2/10\n",
      "122444/122444 [==============================] - 89s 730us/step - loss: 1.2836\n",
      "----- Generating text after Epoch: 1\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \" this anymore i need someone to hold me \"\n",
      " this anymore i need someone to hold me and i got the things that i don't want that i stay that i don't wanna spend that i got that i got that i don't want that i don't want that i stay one that i don't wanna stand that i don't want that i got a bandy that i don't want that i don't want that i ain't throwing on the time that i don't want that i got a gang that i don't say you want that you got my bed and i'm trying that i got my nigga t\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \" this anymore i need someone to hold me \"\n",
      " this anymore i need someone to hold me yeah and you got it contred to the girl oh yeah i don't mill the fuck and i got now and i say you ain't trust it money that that you want that the fame that i know on the contor and that yeah you got the faith it i'm still word it that what i'm straight that i make a bar make it you know and we don't not the whole that shit done it was ain't even nothing on the bation on the time i know how i'm to\n",
      "Epoch 3/10\n",
      "122444/122444 [==============================] - 89s 726us/step - loss: 1.2644\n",
      "----- Generating text after Epoch: 2\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \" i see is fireworks every night is firew\"\n",
      " i see is fireworks every night is fireworks to the bout to me when i stand on the things that i would see it i don't wanna be the cash the way it and i started me i been the beat and i stand to be for the women i want to the way i can tell me they loving the way i can tell me they wish you you don't ende no the controlla they loving the way it work the things i don't wanna be i don't wanna be for me i been the beat the whole that i wou\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \" i see is fireworks every night is firew\"\n",
      " i see is fireworks every night is fireworks to make me now you don't know you the places to the call a compore to come the news that i like it if i don't winder that you got it money and it from the less you don't can't see my mind it i'm poo but i don't was the crust there's say you been ever time it for the things we'll deed i can tell you they loving me and i won a good they all i got the way everything you need my man you the she s\n",
      "Epoch 4/10\n",
      "122444/122444 [==============================] - 91s 744us/step - loss: 1.25361\n",
      "----- Generating text after Epoch: 3\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \" not your friend not your guy i'm not yo\"\n",
      " not your friend not your guy i'm not you don't want the real i got it i get it i get it i get it i get it it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get it i get \n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \" not your friend not your guy i'm not yo\"\n",
      " not your friend not your guy i'm not you don't know and this and 'em that i i thought i don't be the bottom niggas i got me they got to go gradygain i don't mean i don't in my go the things it always how i got party and i'm not good go go gay you don't know you the things and they w"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/nikolaevra/.local/lib/python3.5/site-packages/ipykernel_launcher.py:3: RuntimeWarning: divide by zero encountered in log\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ant the tate of the guill never be waitin' it i need me and they got a ming i want it they got a grame the wast i got it we're here there now you know it th\n",
      "Epoch 5/10\n",
      "122444/122444 [==============================] - 89s 724us/step - loss: 1.2385\n",
      "----- Generating text after Epoch: 4\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"nk all day if you don't start in the mor\"\n",
      "nk all day if you don't start in the more i got a lot of me i got a lot of my friends they know that i got a bandy the game and i got me i got a lot about me i got it i get it i get it i'm too good they got it they love i can't see it i'm the bound to spend all the bottom now when i'm a man like the bottom now when i got it i guess i get it i get it i'm the guest i get it i get it i'm too good to see the bone and the check i don't have \n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"nk all day if you don't start in the mor\"\n",
      "nk all day if you don't start in the morer in the connect in the bound no love i want the check on the cloth no so show you cannot bout a say i'm ball i'm snople with you they got a really bed shit and my big the boung all my face yeah i ain't even know you know the word to see i love the check i got the low i know the ound the bound when i do look the tefened i ain't ass for my face you know i'm the mand the greatest they love in the c\n",
      "Epoch 6/10\n",
      "122444/122444 [==============================] - 92s 749us/step - loss: 1.2291\n",
      "----- Generating text after Epoch: 5\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"all light up hey guru tell hom' to go to\"\n",
      "all light up hey guru tell hom' to go to me i want to the bottom now the bout i go i'm a nigga with me when i don't see you now i got to wastin' on the bad bitch i been hurt i'm a back then i don't can but i don't know that i done you can believe i stay the bottom now we started the back then i stay to me when i don't can been the are because i stay to be for me i don't be the bottom now we start to the bottom now we gone the bottom now\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"all light up hey guru tell hom' to go to\"\n",
      "all light up hey guru tell hom' to go to comporer way it when i hear the artand she bent and the bout me get a but i got money they handle out to party with i'm gone and i'mma go hard and in the games so i could be for i'm the man and like a back wastin' here with they still be with no with your name yeah yeah yeah yeah yeah yeah yeah you see when you could be then i done straight the danger i'm just i take it was always in from me face\n",
      "Epoch 7/10\n",
      "122444/122444 [==============================] - 97s 790us/step - loss: 1.2177\n",
      "----- Generating text after Epoch: 6\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \" a wednesday night girl i'm lonely i'll \"\n",
      " a wednesday night girl i'm lonely i'll be all my big to fack the bottom now i'm to the baround to the cars and i'm the bout to me and i'm been faker some i got a blam the shit i'm all a good to the things you all the car way to the bottom now the pirton the boosed i'm the cars the bottom now the shit i'm the game to me the boosed to the bottom now the cars the shit i'm to be all my time i got the bottom now the way it the shit i'm the \n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \" a wednesday night girl i'm lonely i'll \"\n",
      " a wednesday night girl i'm lonely i'll but i got a coming and i'm to spend me i got a like the check me you in the cars out to the condoom changed me i would said we boutht on the city me the same things that some i made my things that shit show it you gotta star me to the come fore man i know i'm saying it can do the hop and my this is the dance still cause you not a wake all the shit 'em all i got me all my friends now i'm sing to we\n",
      "Epoch 8/10\n",
      "122444/122444 [==============================] - 98s 803us/step - loss: 1.2100\n",
      "----- Generating text after Epoch: 7\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"it feel a way feel a way young nigga fee\"\n",
      "it feel a way feel a way young nigga feeling like a lot of shit i go all i got the shit i got the work that i got a bandreture i got a bent i got a real but you say you can don't have to me and the compory the creach cree tio still went and i got it i know you gotta stand that i don't wanna be loved to me i got the way it for me i got the work that i started from the fuck and we go threat the real they loving the real nigga we got a pri\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"it feel a way feel a way young nigga fee\"\n",
      "it feel a way feel a way young nigga feel a little all your like a place i do what you say you you go to be in the lips the child in my niggas still one my famor for me i got paid the high to me but would say you know you know you like i go that went the money to the creas and i can't but the right wine but then go are do woah to see a stand my high yave me a real go sleeple what i would never got the way wouldn't wanna take you all so \n",
      "Epoch 9/10\n",
      "122444/122444 [==============================] - 95s 773us/step - loss: 1.2086\n",
      "----- Generating text after Epoch: 8\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"eady i'm blem for real i might just say \"\n",
      "eady i'm blem for real i might just say you they had the shit i get it i get it it's okay it's okay you could true that you can tell me the boy it was and the paities i don't want the cause i got pain i'm trying to be it i'm so i'm trying to see it i'm trying to stand me and i'm start to the talkin' on my secles that i can't be the can party that i'm a don't feel the same i got the shout out to the things i got it i'm some the boy it wa\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"eady i'm blem for real i might just say \"\n",
      "eady i'm blem for real i might just say he hear with my hintess got it you need a banda i can protend i ain't nothing a say i'm hangy no real you gotta take it i said i stead i got pain they had to me a pibul but i'm live it don't take me when of you on the way i wanna been threations it should trust i had to take me now i'm trying to me i got a prot up on me everyone the things and i'm say i'm the prot and riched to get my where i got \n",
      "Epoch 10/10\n",
      "122444/122444 [==============================] - 95s 776us/step - loss: 1.1977\n",
      "----- Generating text after Epoch: 9\n",
      "----- diversity: 0.2\n",
      "----- Generating with seed: \"ing home just hold on we're going home g\"\n",
      "ing home just hold on we're going home go and the low to peace the boy what i don't wanna see it want the way that i did the boy it work the boy and we bout to my nigga that i did it was and i did it was the bout what i start to be all the boy i got me and i started been give it i don't even know that i got no head to be in the cash i just wanna see me fuck a bentle and i did i did that i did it was and i be going in the bead for you ni\n",
      "----- diversity: 0.5\n",
      "----- Generating with seed: \"ing home just hold on we're going home g\"\n",
      "ing home just hold on we're going home go with i es to was smoke one party in the cready my life i'm gone i got high in the way did to put the call say i'm bales i did it show the word we go to make the boy it we did in the boy what i just got you worst the bout to put the boy one shit of the condenger was that's on some there oh yeah yeah yeah yeah yeah yeah yeah yeah yeah yeah yeah yeah yeah ya never take to be scare the life i just g\n"
     ]
    }
   ],
   "source": [
    "print_callback = LambdaCallback(on_epoch_end=on_epoch_end)\n",
    "\n",
    "history = model.fit(\n",
    "    x, \n",
    "    y,\n",
    "    batch_size=128,\n",
    "    epochs=10,\n",
    "    callbacks=[print_callback]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f73a3d53dd8>]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f73a3d87dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "plt.plot(history.history['loss'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_output():\n",
    "    generated = ''\n",
    "    usr_input = input(\"Write the beginning of your poem, the Drake machine will complete it. Your input is: \")\n",
    "\n",
    "    sentence = ('{0:0>' + str(Tx) + '}').format(usr_input).lower()\n",
    "    generated += usr_input \n",
    "\n",
    "    sys.stdout.write(\"\\n\\nHere is your poem: \\n\\n\") \n",
    "    sys.stdout.write(usr_input)\n",
    "    for i in range(400):\n",
    "\n",
    "        x_pred = np.zeros((1, Tx, len(chars)))\n",
    "\n",
    "        for t, char in enumerate(sentence):\n",
    "            if char != '0':\n",
    "                x_pred[0, t, char_indices[char]] = 1.\n",
    "\n",
    "        preds = model.predict(x_pred, verbose=0)[0]\n",
    "        next_index = sample(preds, temperature = 0.2)\n",
    "        next_char = indices_char[next_index]\n",
    "\n",
    "        generated += next_char\n",
    "        sentence = sentence[1:] + next_char\n",
    "\n",
    "        sys.stdout.write(next_char)\n",
    "        sys.stdout.flush()\n",
    "\n",
    "        if next_char == '\\n':\n",
    "            continue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write the beginning of your poem, the Drake machine will complete it. Your input is: twenty percent pain thirty percent skill\n",
      "\n",
      "\n",
      "Here is your poem: \n",
      "\n",
      "twenty percent pain thirty percent skill before the body i don't even won a real you know what i start to see it i'm trying to be all the city party the conders in the can but i got it i got no heave you don't wanna see it was and wine it i got no head to me and i would be start to me i got my word to me girl what i did i did it i won't dead that for the boy and the way the bout it i get it i get it i get it i get it i get it i get it i"
     ]
    }
   ],
   "source": [
    "Tx = 40\n",
    "generate_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "import utils"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "utils.save_model_weights(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
